home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy-1.1 (sources only) / mindy-1.1 / interp / str.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-26  |  5.4 KB  |  222 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: str.c,v 1.8 94/07/26 00:40:23 wlott Exp $
  27. *
  28. * This file implements strings.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include <stdio.h>
  33. #include <string.h>
  34.  
  35. #include "mindy.h"
  36. #include "gc.h"
  37. #include "coll.h"
  38. #include "class.h"
  39. #include "char.h"
  40. #include "module.h"
  41. #include "num.h"
  42. #include "bool.h"
  43. #include "obj.h"
  44. #include "str.h"
  45. #include "error.h"
  46. #include "type.h"
  47. #include "print.h"
  48. #include "list.h"
  49. #include "def.h"
  50. #include "sym.h"
  51.  
  52.  
  53. obj_t obj_ByteStringClass = 0;
  54.  
  55. obj_t make_string(char *chars)
  56. {
  57.     int len = strlen(chars);
  58.     obj_t res = alloc(obj_ByteStringClass, sizeof(struct string) + len + 1);
  59.  
  60.     obj_ptr(struct string *, res)->len = len;
  61.     strcpy(obj_ptr(struct string *, res)->chars, chars);
  62.  
  63.     return res;
  64. }
  65.  
  66. obj_t alloc_string(int len)
  67. {
  68.     obj_t res = alloc(obj_ByteStringClass, sizeof(struct string) + len + 1);
  69.  
  70.     obj_ptr(struct string *, res)->len = len;
  71.     obj_ptr(struct string *, res)->chars[len] = '\0';
  72.  
  73.     return res;
  74. }
  75.  
  76.  
  77. /* Dylan routines. */
  78.  
  79. static obj_t dylan_str_element(obj_t str, obj_t index, obj_t def)
  80. {
  81.     int i = fixnum_value(index);
  82.  
  83.     if (0 <= i && i < obj_ptr(struct string *, str)->len)
  84.     return int_char(string_chars(str)[i]);
  85.     else if (def != obj_Unbound)
  86.     return def;
  87.     else {
  88.     error("No element %= in %=", index, str);
  89.     return NULL;
  90.     }
  91. }
  92.  
  93. static obj_t dylan_str_element_setter(obj_t value, obj_t str, obj_t index)
  94. {
  95.     int i = fixnum_value(index);
  96.  
  97.     if (0 <= i && i < obj_ptr(struct string *, str)->len)
  98.     string_chars(str)[i] = char_int(value);
  99.     else
  100.     error("No element %= in %=", index, str);
  101.  
  102.     return value;
  103. }
  104.  
  105. static obj_t dylan_str_size(obj_t str)
  106. {
  107.     return make_fixnum(obj_ptr(struct string *, str)->len);
  108. }
  109.  
  110. static obj_t dylan_str_make(obj_t class, obj_t size, obj_t fill)
  111. {
  112.     obj_t res;
  113.     int len;
  114.     unsigned char *ptr;
  115.     int fill_char;
  116.  
  117.     if (!instancep(size, obj_IntegerClass))
  118.     error("Bogus size: for make %=: %=", class, size);
  119.     len = fixnum_value(size);
  120.  
  121.     if (len < 0)
  122.     error("Bogus size: for make %=: %=", class, size);
  123.  
  124.     if (!instancep(fill, obj_CharacterClass))
  125.     error("Bogus fill: for make %=: %=", class, fill);
  126.     fill_char = char_int(fill);
  127.  
  128.     res = alloc_string(len);
  129.  
  130.     ptr = string_chars(res);
  131.     while (len-- > 0)
  132.     *ptr++ = fill_char;
  133.     *ptr = '\0';
  134.  
  135.     return res;
  136. }
  137.  
  138.  
  139. /* Printer support. */
  140.  
  141. static void print_string(obj_t str)
  142. {
  143.     int len = obj_ptr(struct string *, str)->len;
  144.     unsigned char *ptr = string_chars(str);
  145.  
  146.     putchar('"');
  147.     while (len-- > 0) {
  148.         if (*ptr == '\n')
  149.         printf("\\n");
  150.     else if (*ptr < ' ' || *ptr > '~')
  151.         printf("\\%03o", *ptr);
  152.     else if (*ptr == '"')
  153.         printf("\\\"");
  154.     else
  155.         putchar(*ptr);
  156.     ptr++;
  157.     }
  158.     putchar('"');
  159. }
  160.  
  161.  
  162. /* GC stuff. */
  163.  
  164. static int scav_string(struct object *ptr)
  165. {
  166.     struct string *str = (struct string *)ptr;
  167.  
  168.     return sizeof(struct string) + str->len + 1;
  169. }
  170.  
  171. static obj_t trans_string(obj_t string)
  172. {
  173.     return transport(string,
  174.              sizeof(struct string)
  175.                + obj_ptr(struct string *, string)->len
  176.                + 1);
  177. }
  178.  
  179. void scavenge_str_roots(void)
  180. {
  181.     scavenge(&obj_ByteStringClass);
  182. }
  183.  
  184.  
  185. /* Init stuff. */
  186.  
  187. void make_str_classes(void)
  188. {
  189.     obj_ByteStringClass = make_builtin_class(scav_string, trans_string);
  190. }
  191.  
  192. void init_str_classes(void)
  193. {
  194.     init_builtin_class(obj_ByteStringClass, "<byte-string>",
  195.                obj_VectorClass, obj_StringClass, NULL);
  196.     def_printer(obj_ByteStringClass, print_string);
  197. }
  198.  
  199. void init_str_functions(void)
  200. {
  201.     define_method("element",
  202.             list2(obj_ByteStringClass, obj_IntegerClass),
  203.             FALSE, list1(pair(symbol("default"), obj_Unbound)), FALSE,
  204.             obj_CharacterClass, dylan_str_element);
  205.     define_method("element-setter",
  206.           list3(obj_CharacterClass,
  207.             obj_ByteStringClass,
  208.             obj_IntegerClass),
  209.           FALSE, obj_False, FALSE,
  210.           obj_ObjectClass, dylan_str_element_setter);
  211.     define_method("size", list1(obj_ByteStringClass),
  212.           FALSE, obj_False, FALSE, obj_IntegerClass, dylan_str_size);
  213.     define_method("make", list1(singleton(obj_StringClass)), FALSE,
  214.           list2(pair(symbol("size"), make_fixnum(0)),
  215.             pair(symbol("fill"), int_char('\0'))),
  216.           FALSE, obj_ByteStringClass, dylan_str_make);
  217.     define_method("make", list1(singleton(obj_ByteStringClass)), FALSE,
  218.           list2(pair(symbol("size"), make_fixnum(0)),
  219.             pair(symbol("fill"), int_char('\0'))),
  220.           FALSE, obj_ByteStringClass, dylan_str_make);
  221. }
  222.